const app = getApp()

var serviceUUID = [] //主 service 的 uuid 列表  serviceUUID[0] = "0000FEE0-0000-1000-8000-00805F9B34FB
var notifyUUID = "0000FEE2-0000-1000-8000-00805F9B34FB"; //notify UUID
var writeUUID = "0000FEE1-0000-1000-8000-00805F9B34FB"; //写读 UUID，这里代码没用到，但写上去方便使用
var deviceId = ''; //用于区分设备的 id

var _deviceId = '';
var _serviceId = '';
var _characteristicId = '';
var string16 = null //16进制码
var display_floor = null

//获取所需键值的索引
function inArray(arr, key, val) {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i][key] === val) {
      return i;
    }
  }
  return -1;
}
//目标楼层发送，设置好默认的楼层号在数组中，方便调用，注：这里是测试用的，楼层有限所以用这种方法，如果要任意楼层，其实可以在文本框中直接输入16进制码，但需要去进行逻辑的，修改如果改成这个模式，这样子就可以无限制，就不用重复去更新小程序
//如果要加入-3层就在数组的头部加入，以此类推-4加入新的头部。。。如果要加入正数层，比如3层，就在数组的尾部加入，如果要新加入4层，就在新的尾部加入，以此类推
function sendFloorInfo(num) {
  let arrs = ["7FF7182916271122334455660D60CA010203040506070809101112C2",
    "7FF7182916271122334455660D60C9010203040506070809101112C1",
    "0", //这里0是为了占位用的
    "7FF7182916271122334455660D600101020304050607080910111209",
    "7FF7182916271122334455660D60020102030405060708091011120A"
  ]
  return arrs[num]
}
//校准楼层，0层是结束校准
function calibrationFloorInfo(num) {
  // -2 -1 0(结束校准) 1 2
  let arrs = ["7FF719291627112233445566OE5902CA010203040506070809101112FB", "7FF7192916271122334455660E5902C9010203040506070809101112F8",
    "7FF7192916271122334455660E59030201020304050607080910111232",
    "7FF719291627112233445566OE59010101020304050607080910111233", "7FF7192916271122334455660E59020201020304050607080910111233"
  ]
  return arrs[num]
}
// ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {
  var hexArr = Array.prototype.map.call(
    new Uint8Array(buffer),
    function (bit) {
      return ('00' + bit.toString(16)).slice(-2)
    }
  )
  return hexArr.join('');
}
//获取楼层29和30位的字节码，这两位是对电梯在几楼的判断
function getCurrentFloor(chs) {
  for (let i = 0; i < chs.length; i++) {
    console.log(chs[i].uuid)
    if (chs[i].uuid == notifyUUID) {
      display_floor = parseInt(chs[i].value.substring(28, 30), 16)
      console.log(chs[i].value, display_floor)
      console.log(chs[i].value[28], chs[i].value[29])
    }
  }
  return display_floor
}

Page({
  data: {
    connected: false, //是否连接的判断，连接了才会展示数据
    chs: [], //特征值（uuid)列表
    deviceList: [], //设备列表
    display_floor: '' //展示的当前楼层数
  },
  //初始化蓝牙模块
  initBlue() {
    var that = this;
    wx.openBluetoothAdapter({ //调用微信小程序api 打开蓝牙适配器接口
      success: function (res) {
        console.log(res)
        wx.showToast({
          title: '初始化成功',
          icon: 'success',
          duration: 800
        })
        that.findBlue(); //2.0
      },
      fail: function (res) { //如果手机上的蓝牙没有打开，可以提醒用户
        wx.showToast({
          title: '请开启蓝牙',
          icon: 'error',
          duration: 1000
        })
      }
    })
  },
  //设置待发送的目标/校准楼层信息，等待发送
  sendfloor_InfoBLE(event) {
    const {
      targetFloor
    } = event.detail.value;
    const {
      calibrationFloor
    } = event.detail.value;
    console.log(targetFloor + 2, calibrationFloor) //楼层对应关系
    var dataString = null
    // 字符串转字节数组
    if (targetFloor) {
      console.log(dataString)
      dataString = sendFloorInfo(parseInt(targetFloor) + 2)
    } else if (calibrationFloor) {
      console.log(dataString)
      dataString = calibrationFloorInfo(parseInt(calibrationFloor) + 2)
    }
    console.log(dataString)
    const bytes = [];
    //对错误进行捕获，当没输入值的时候是null,当数组越界的时候是undefind
    try {    
      for (let i = 0; i < dataString.length; i = i + 2) {
        bytes.push(parseInt(dataString.substring(i, i + 2), 16));
      }
      wx.showToast({
        title: '设置成功',
      })
    } catch (err) {
      console.log(err)
      wx.showToast({
        title: '请检查一下是否输入值或者数组越界',
        icon: 'error'
      })
    }
    // 2. 创建 ArrayBuffer 和 DataView  
    let buffer = new ArrayBuffer(bytes.length);
    let dataView = new DataView(buffer);
    // 3. 使用 DataView 设置值  
    for (let i = 0; i < bytes.length; i++) {
      dataView.setUint8(i, bytes[i]);
    }
    string16 = buffer
    console.log(buffer)
  },
  //搜索蓝牙设备，并开始连接
  findBlue() {
    var that = this
    //开始搜索蓝牙
    wx.startBluetoothDevicesDiscovery({
      allowDuplicatesKey: false,
      interval: 0,
      success: function (res) {
        console.log(res);
        // wx.showLoading({
        //     title: '正在搜索设备',
        // })
        // that.getBlue()//3.0
      }
    })
    //页面渲染过滤后的蓝牙列表
    wx.getBluetoothDevices({
      success: function (res) {
        console.log(res) //蓝牙列表
        let arr = []
        res.devices.forEach(item => {
          //这里的Aoting_724UG是自己设置的蓝牙名称
          if (item.name != '未知设备' && item.name.startsWith("Aoting")) {
            arr.push(item)
          }
        })
        that.setData({
          deviceList: arr
        })
        console.log(that.data.deviceList)
      }
    })
  },
  //停止扫描
  stopBluetoothDevicesDiscovery() {
    wx.stopBluetoothDevicesDiscovery()
  },
  //创建蓝牙连接
  createBLEConnection(e) {
    const ds = e.currentTarget.dataset
    const deviceId = ds.deviceId
    const name = ds.name
    wx.createBLEConnection({
      deviceId,
      success: (res) => {
        this.setData({
          connected: true,
          name,
          deviceId,
        })
        this.getBLEDeviceServices(deviceId)
      }
    })
    this.stopBluetoothDevicesDiscovery()
  },
  //断开蓝牙连接
  closeBLEConnection() {
    wx.closeBLEConnection({
      deviceId: this.data.deviceId
    })
    this.setData({
      connected: false,
      chs: [],
      canWrite: false,
    })
  },
  //获取蓝牙设备上所有服务
  getBLEDeviceServices(deviceId) {
    wx.getBLEDeviceServices({
      deviceId,
      success: (res) => {
        console.log(res);
        for (let i = 0; i < res.services.length; i++) { //res.services.length
          if (res.services[i].isPrimary) {
            this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
            // console.log(i)
            // return
          }
        }
      }
    })
  },
  //获取服务对应特征值
  getBLEDeviceCharacteristics(deviceId, serviceId) {
    wx.getBLEDeviceCharacteristics({
      deviceId,
      serviceId,
      success: (res) => {
        console.log('getBLEDeviceCharacteristics success', res.characteristics)
        for (let i = 0; i < res.characteristics.length; i++) {
          let item = res.characteristics[i]
          if (item.properties.read) {
            wx.readBLECharacteristicValue({
              deviceId,
              serviceId,
              characteristicId: item.uuid,
            })
          }
          //如果读到的特征值是写入
          if (item.properties.write) {
            this.setData({
              canWrite: true
            })
            this._deviceId = deviceId
            this._serviceId = serviceId
            this._characteristicId = item.uuid
          }
          //如果读到的特征值是读取
          if (item.properties.notify || item.properties.indicate) {
            wx.notifyBLECharacteristicValueChange({
              deviceId,
              serviceId,
              characteristicId: item.uuid,
              state: true,
            })
          }
        }
      },
      fail(res) {
        console.error('getBLEDeviceCharacteristics', res)
      }
    })
    // 操作之前先监听，保证第一时间获取数据
    wx.onBLECharacteristicValueChange((characteristic) => {
      const idx = inArray(this.data.chs, 'uuid', characteristic.characteristicId)
      const data = {}
      if (idx === -1) {
        data[`chs[${this.data.chs.length}]`] = {
          uuid: characteristic.characteristicId,
          value: ab2hex(characteristic.value)
        }
      } else {
        data[`chs[${idx}]`] = {
          uuid: characteristic.characteristicId,
          value: ab2hex(characteristic.value)
        }
      }
      // data[`chs[${this.data.chs.length}]`] = {
      //   uuid: characteristic.characteristicId,
      //   value: ab2hex(characteristic.value)
      // }
      this.setData(data)
      console.log(getCurrentFloor(this.data.chs))
      display_floor = getCurrentFloor(this.data.chs) //获取当前楼层状态
      let lc_info = ''
      //把读到的值进行楼层判断
      switch (display_floor) {
        case 202:
          lc_info = "负2楼";
          break;
        case 201:
          lc_info = "负1楼"
          break;
        case 1:
          lc_info = "1楼"
          break;
        case 2:
          lc_info = "2楼"
          break;
        default:
          lc_info = "未知楼层"
          break;
      }
      if (lc_info != '') {
        console.log(1)
        this.setData({
          display_floor: lc_info //这个貌似是异步的，所以加个操作让它同步
        })
      }
      this.setData(data)
    })
  },
  //为了传值置空用的
  writeBLE() {
    this.writeBLECharacteristicValue('')
  },
  //向设备写入数据
  writeBLECharacteristicValue(param) {
    // 向蓝牙设备发送一个0x00的16进制数据
    //console.log(floorInfo, this._deviceId, this._serviceId, this._characteristicId)
    console.log(param)
    if (param != '') string16 = param
    //向蓝牙写入
    wx.writeBLECharacteristicValue({
      deviceId: this._deviceId,
      serviceId: this._serviceId,
      characteristicId: this._characteristicId,
      value: string16,
      success: function (res) {
        console.log(res.errMsg);
        console.log("发送成功");
        wx.showToast({
          title: '发送成功',
        })
      },
      fail: function (res) {
        console.log(res);
        wx.showToast({
          title: "发送失败.请检查是否连接蓝牙" + res.errMsg,
          icon: 'error'
        })
        console.log("发送失败,请检查是否设置");
        if (res.errCode == 10006) {
          that.setData({
            isconnect: false
          })
        }
      }
    })
  },
  //结束流程，把初始化，扫描全关了，此时再连是连接不上的，得重新扫描进行初始化
  closeBluetoothAdapter() {
    wx.closeBluetoothAdapter()
  },
  //查询指令
  check() {
    let check_num = "7FF7172910271122334455660C6101020304050607080910111201"
    const bytes = []
    for (let i = 0; i < check_num.length; i = i + 2) {
      bytes.push(parseInt(check_num.substring(i, i + 2), 16));
    }
    // 创建 ArrayBuffer 和 DataView  
    let buffer = new ArrayBuffer(bytes.length);
    let dataView = new DataView(buffer);
    // 使用 DataView 设置值  
    for (let i = 0; i < bytes.length; i++) {
      dataView.setUint8(i, bytes[i]);
    }
    this.writeBLECharacteristicValue(buffer)
  }
})